/**Changed Gaurav
#ifdef PARALLEL
*/

#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <syslog.h>

#include "clam.h"
#include "serial.h"
#include "parallel.h"

int pingLoop;
extern float *distrib;
extern int validDistribution;

static void noopHandler(int sig) 
{
	pingLoop = 1;
	return;
}

int readLoop(int socket, void* data, int len)
{
	int got;
	int get;
	struct itimerval oldalarm;
	struct itimerval newalarm;

	struct sigaction ping_signal;
	struct sigaction old_sigpipe;
	struct sigaction old_alarm;

	/* Save the state of the alarm from before & disable alarm */
	memset(&newalarm, 0, sizeof(newalarm));
	setitimer(ITIMER_REAL, &newalarm, &oldalarm);

	/* Setup a handler for our alarm/sigpipe that triggers a ping */
	ping_signal.sa_handler = &noopHandler;
	sigemptyset(&ping_signal.sa_mask);
	ping_signal.sa_flags = 0; /* note: no SA_RESTART */
 
   	/* Register this handler on sig_alarm */
	sigaction(SIGALRM, &ping_signal, &old_alarm);

	/* Register this handler on sig_pipe */
   	sigaction(SIGPIPE, &ping_signal, &old_sigpipe);
	
	/* Prepare to send a keepalive ping in 5 seconds */
	pingLoop = 0;
	newalarm.it_value.tv_sec = 5;
	newalarm.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &newalarm, 0);

	for (got = 0; got < len; got += get)
	{
		get = read(socket, data+got, len-got);

		if (pingLoop)
		{
		    u_int32_t ping = htonl(DAEMON_KEEP_ALIVE_PING);
			if (write(socket, &ping, sizeof(ping)) != sizeof(ping))
			{
				memset(&newalarm, 0, sizeof(newalarm));
				setitimer(ITIMER_REAL, &newalarm, 0);
				sigaction(SIGALRM, &old_alarm, 0);
				sigaction(SIGPIPE, &old_sigpipe, 0);
   				setitimer(ITIMER_REAL, &oldalarm, 0);
				return -1;
			}

			pingLoop = 0;
			get = 0;
			setitimer(ITIMER_REAL, &newalarm, 0);
		}
		else if (get < 0) 
		{
			memset(&newalarm, 0, sizeof(newalarm));
			setitimer(ITIMER_REAL, &newalarm, 0);
			sigaction(SIGALRM, &old_alarm, 0);
			sigaction(SIGPIPE, &old_sigpipe, 0);
			setitimer(ITIMER_REAL, &oldalarm, 0);
			return -1;
		}
	}
	
	memset(&newalarm, 0, sizeof(newalarm));
	setitimer(ITIMER_REAL, &newalarm, 0);
	sigaction(SIGALRM, &old_alarm, 0);
	sigaction(SIGPIPE, &old_sigpipe, 0);
	setitimer(ITIMER_REAL, &oldalarm, 0);

	return len;
}

int writePz(const struct tmpPz* wpz, int socket)
{
	union chunk1 out[21];
	
	assert(sizeof(float)       == 4);
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk1) == 8);
	assert(sizeof(out)         == 21*8); /*WMN changed 23 to 21 1/18/05*/

	//   printf("writePz: must be updated to write doubles!");
    //    exit(0);
    
    
	printf("\nWriting double: %e ; ",  wpz->cutFlt);
	printf("Writing float: %f ; \n",wpz->burFlt);

	out[ 0].i[0] = htonl(wpz->tol);
	out[ 1].i[0] = htonl(wpz->fromendInt);
	out[ 2].f[0] = wpz->burFlt;
	out[ 3].d    = wpz->cutFlt;
	out[ 4].i[0] = htonl(wpz->diffInt);
	out[ 5].i[0] = htonl(wpz->killInt);
	out[ 6].i[0] = htonl(wpz->logFlag);
	out[ 7].i[0] = htonl(wpz->stdFlag);
	out[ 8].i[0] = htonl(wpz->bestInt);
	out[9].i[0] = htonl(wpz->minVal);
	out[10].i[0] = htonl(wpz->maxVal);
	out[11].i[0] = htonl(wpz->seqFlag);
	out[12].i[0] = htonl(wpz->autoaddFlag);
	out[13].i[0] = htonl(wpz->adjust);
	out[14].i[0] = htonl(wpz->gap);
	out[15].i[0] = htonl(wpz->shuffle);
	out[16].i[0] = htonl(wpz->ctg);
	out[17].i[0] = htonl(wpz->offset);
	out[18].f[0] = wpz->p_align;
	out[19].i[0] = htonl(wpz->ok_olap);
	out[20].i[0] = htonl(wpz->useSz);
	
	//	printf("Write Cut float: %e \n",out[4].f);

	if (write(socket, &out, sizeof(out)) != sizeof(out)) return -1;
	return 0;
}

int readPz(struct tmpPz* wpz, int socket)
{
	union chunk1 out[21];
	
	assert(sizeof(float)       == 4);
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk1) == 8);
	assert(sizeof(out)         == 21*8); /*WMN changed 23 to 21 1/18/05 */

	if (readLoop(socket, &out, sizeof(out)) != sizeof(out)) return -1;

	wpz->tol         = htonl(out[ 0].i[0]);
	wpz->fromendInt  = htonl(out[ 1].i[0]);
	wpz->burFlt      = out[ 2].f[0];
	wpz->cutFlt      = out[ 3].d;
	wpz->diffInt     = htonl(out[ 4].i[0]);
	wpz->killInt     = htonl(out[ 5].i[0]);
	wpz->logFlag     = htonl(out[ 6].i[0]);
	wpz->stdFlag     = htonl(out[ 7].i[0]);
	wpz->bestInt     = htonl(out[ 8].i[0]);
	wpz->minVal      = htonl(out[9].i[0]);
	wpz->maxVal      = htonl(out[10].i[0]);
	wpz->seqFlag     = htonl(out[11].i[0]);
	wpz->autoaddFlag = htonl(out[12].i[0]);
	wpz->adjust      = htonl(out[13].i[0]);
	wpz->gap         = htonl(out[14].i[0]);
	wpz->shuffle     = htonl(out[15].i[0]);
	wpz->ctg         = htonl(out[16].i[0]);
	wpz->offset      = htonl(out[17].i[0]);
	wpz->p_align     = out[18].f[0];
	wpz->ok_olap     = htonl(out[19].i[0]);
	wpz->useSz       = htonl(out[20].i[0]);
	
	return 0;
}

union projectChunk
{
	union chunk c[10];
	char        buf[10*4 + 50 + 128*2 + 400 + 800];
};

int writeProj(const struct project* proj, int socket)
{
	union projectChunk pc;
	int i;
	
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk) == 4);
	
	pc.c[0].i = ntohl(proj->automsg);
	pc.c[1].i = ntohl(proj->avgbandsize);
	/*	pc.c[2].i = ntohl(proj->genomesize); */
	pc.c[3].i = ntohl(proj->avginsertsize);
	pc.c[4].i = ntohl(proj->maxband);
	pc.c[5].i = ntohl(proj->variable);
	pc.c[6].i = ntohl(proj->eq2);
	pc.c[7].i = ntohl(proj->gel_len);
	pc.c[8].i = ntohl(proj->MinClip);
	pc.c[9].i = ntohl(proj->MaxClip);
	
	memcpy (&pc.buf[ 40], proj->mapname,     50);
	strncpy(&pc.buf[ 90], proj->uncfile,    128);
	strncpy(&pc.buf[218], proj->filterfile, 128);

	pc.buf[ 90+127] = 0;
	pc.buf[218+127] = 0;
	
	for (i = 0; i < 4; i++)
	{
		memcpy(&pc.buf[346 + 100*i], &proj->msg [i][0], 100);
		memcpy(&pc.buf[746 + 200*i], &proj->msg2[i][0], 200);
	}
	
	if (write(socket, &pc, sizeof(pc)) != sizeof(pc)) return -1;
	return 0;
}

int readProj(struct project* proj, int socket)
{
	union projectChunk pc;
	int i;
	
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk) == 4);
	
	if (readLoop(socket, &pc, sizeof(pc)) != sizeof(pc)) return -1;

	proj->automsg       = ntohl(pc.c[0].i);
	proj->avgbandsize   = ntohl(pc.c[1].i);
	/*	proj->genomesize    = ntohl(pc.c[2].i); */
	proj->avginsertsize = ntohl(pc.c[3].i);
	proj->maxband       = ntohl(pc.c[4].i);
	proj->variable      = ntohl(pc.c[5].i);
	proj->eq2           = ntohl(pc.c[6].i);
	proj->gel_len	    = ntohl(pc.c[7].i);
	proj->MinClip       = ntohl(pc.c[8].i);
	proj->MaxClip       = ntohl(pc.c[9].i);
	
	memcpy (proj->mapname,    &pc.buf[ 40],  50);
	strncpy(proj->uncfile,    &pc.buf[ 90], 128);
	strncpy(proj->filterfile, &pc.buf[218], 128);
	
	for (i = 0; i < 4; i++)
	{
		memcpy(&proj->msg [i][0], &pc.buf[346 + 100*i], 100);
		memcpy(&proj->msg2[i][0], &pc.buf[746 + 200*i], 200);
	}
	
	return 0;
}

int writeCpM(const struct CpMvar* cpm, int socket)
{
	union chunk out[14];  /*fred 7/30/02 -- added one position for useREP*/
	
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk) == 4);
	assert(sizeof(out)         == 14*4);
	
	out[0].i = htonl(cpm->autoFlag);
	out[1].i = htonl(cpm->maxCpM);
	out[2].i = htonl(cpm->useFlag);
	out[3].i = htonl(cpm->usePCR);
	out[4].i = htonl(cpm->useYBP);

 	/* sness */
	out[5].i = htonl(CpM[0].nm);
	out[6].f = CpM[0].cut;
	out[7].i = htonl(CpM[1].nm);
	out[8].f = CpM[1].cut;
	out[9].i = htonl(CpM[2].nm);
	out[10].f = CpM[2].cut;
	out[11].i = htonl(CpM[3].nm);
	out[12].f = CpM[3].cut;

	out[13].i = htonl(cpm->useREP);  /*fred 7/30/02*/

	if (write(socket, &out, sizeof(out)) != sizeof(out)) return -1;
	return 0;
}

int readCpM(struct CpMvar* cpm, int socket)
{
	union chunk out[14];  /*fred 7/30/02 -- incremented*/
	
	assert(sizeof(int32_t)     == 4);
	assert(sizeof(char)        == 1);
	assert(sizeof(union chunk) == 4);
	assert(sizeof(out)         == 14*4);
	
	if (readLoop(socket, &out, sizeof(out)) != sizeof(out)) return -1;

	cpm->autoFlag = htonl(out[0].i);
	cpm->maxCpM   = htonl(out[1].i);
	cpm->useFlag  = htonl(out[2].i);
	cpm->usePCR   = htonl(out[3].i);
	cpm->useYBP   = htonl(out[4].i);

	CpM[0].nm = htonl(out[5].i);
	CpM[0].cut = out[6].f;
	CpM[1].nm = htonl(out[7].i);
	CpM[1].cut = out[8].f;
	CpM[2].nm = htonl(out[9].i);
	CpM[2].cut = out[10].f;
	CpM[3].nm = htonl(out[11].i);
	CpM[3].cut = out[12].f;

	cpm->useREP   = htonl(out[13].i);  /*fred 7/30/02*/

	return 0;
}

union acedata_chunk
{
  u_int32_t dat[14];
  char buf[14*4 + (CLONE_SZ+1) + (CLONE_SZ+1) + 10];
};

/* !sness!! */
union marker_chunk 
{ 
  u_int32_t dat[3]; 
  char buf[3*4 + (MARKER_SZ+1)]; 
}; 

int readAcedata(int socket)
{
  u_int32_t in;
  int i, j;
  int size;
  union acedata_chunk ch;
  union marker_chunk mch;
  unsigned long int nmark;
  struct markertop *marker;
  struct markertop *tmpmark;

  if (readLoop(socket, &in, sizeof(in)) != sizeof(in)) return -1;
  size = in = ntohl(in);
  acedata = arrayReCreate(acedata, size+1, CLONE);

  /*  printf("acedata size = %i\n",size); */

  for (i = 0; i < size; i++)
	{
	  if (readLoop(socket, &ch, sizeof(ch)) != sizeof(ch)) return -1;

	  memcpy(arr(acedata, i, CLONE).clone, &ch.buf[14*4], CLONE_SZ+1);
	  memcpy(arr(acedata, i, CLONE).match, &ch.buf[14*4+CLONE_SZ+1], CLONE_SZ+1);
	  memcpy(arr(acedata, i, CLONE).chctg, &ch.buf[14*4+(CLONE_SZ+1)*2], 10);
	 
	  arr(acedata, i, CLONE).ctg      = ntohl(ch.dat[0]);
	  arr(acedata, i, CLONE).oldctg   = ntohl(ch.dat[1]);
	  arr(acedata, i, CLONE).ibc      = ntohl(ch.dat[2]);
	  arr(acedata, i, CLONE).x        = ntohl(ch.dat[3]);
	  arr(acedata, i, CLONE).y        = ntohl(ch.dat[4]);
	  arr(acedata, i, CLONE).mattype  = ntohl(ch.dat[5]);
	  arr(acedata, i, CLONE).parent   = ntohl(ch.dat[6]);
	  arr(acedata, i, CLONE).next     = ntohl(ch.dat[7]);
	  arr(acedata, i, CLONE).highcol  = ntohl(ch.dat[8]);
	  arr(acedata, i, CLONE).selected = ntohl(ch.dat[9]);
	  arr(acedata, i, CLONE).class    = ntohl(ch.dat[10]);
	  arr(acedata, i, CLONE).seqstat  = ntohl(ch.dat[11]);
	  arr(acedata, i, CLONE).seqtype  = ntohl(ch.dat[12]);
	  nmark = ntohl(ch.dat[13]);

	  /* */
	  /* sness - Read the markers */
	  /* */
	  
 	  /* Allocate memory in 'acedata' for our markers */
  	  if (nmark > 0) {
 		/* Allocate memory for markers */
  		arr(acedata, i, CLONE).marker = (struct markertop*) malloc (sizeof(struct markertop));
  		marker = arr(acedata, i, CLONE).marker;
 		for (j = 0; j < nmark-1; j++) {
		  tmpmark = (struct markertop*) malloc (sizeof(struct markertop));
 		  marker->nextmarker = tmpmark;
 		  marker = marker->nextmarker;
 		}
		marker->nextmarker = NULL;

 		/* 'marker' is an easier data structure to work with than */
 		/* 'arr(acedata, i, CLONE).marker' */
  		marker = arr(acedata, i, CLONE).marker;
  
  		for (j = 0; j < nmark; j++) {
		  /* Read the data */
  		  if (readLoop(socket, &mch, sizeof(mch)) != sizeof(mch)) return -1;
	
  		  /* Copy the data to memory */
  		  memcpy(marker->marker, &mch.buf[3*4], MARKER_SZ+1);
  		  marker->markerindex = ntohl(mch.dat[0]);
  		  marker->weak = ntohl(mch.dat[1]);
  		  marker->new = ntohl(mch.dat[2]);

  		  /* Advance to next memory location */
  		  marker = marker->nextmarker;
  		}
  	  } else {
		arr(acedata, i, CLONE).marker = NULL;
	  }
	}

/*   for (i = 0; i < 100; i++) { */
/* 	printf("Clone : i=%i\tname = %s\t%i\t%i\n",i,arr(acedata, i, CLONE).clone, */
/* 		   arr(acedata, i, CLONE).ctg,arr(acedata, i, CLONE).seqtype); */
/*   } */
  
/*   printf("size = %i\n",size); */

  array(acedata, size, CLONE);
  arrayMax(acedata) = size;
  /*  arrayForceFeed(acedata, size); */

/*   for (i = 0; i < arrayMax(acedata); i++) { */
/* 	printf("Clone2 : i=%i\tname = %s\t%i\t%i\n",i,arr(acedata, i, CLONE).clone, */
/* 		   arr(acedata, i, CLONE).ctg,arr(acedata, i, CLONE).seqtype); */
/*   } */
	
  return 0;
}

int writeAcedata(int socket)
{
  /* Get buffered output */
  u_int32_t out;
  int i;
  union acedata_chunk ch;
  union marker_chunk mch;
  unsigned long int nmark = 0;
  CLONE *clone;
  struct markertop *marker;

  out = htonl(arrayMax(acedata));
  if (write(socket, &out, sizeof(out)) != sizeof(out)) return -1;

  /*  printf("acedata size = %i\n",arrayMax(acedata)); */
	
  for (i = 0; i < arrayMax(acedata); i++)
	{
	  memcpy(&ch.buf[14*4], arr(acedata, i, CLONE).clone, CLONE_SZ+1);
	  memcpy(&ch.buf[14*4+CLONE_SZ+1], arr(acedata, i, CLONE).match, CLONE_SZ+1);
	  memcpy(&ch.buf[14*4+(CLONE_SZ+1)*2], arr(acedata, i, CLONE).chctg, 10);
	  
	  ch.dat[ 0] = htonl(arr(acedata, i, CLONE).ctg);
	  ch.dat[ 1] = htonl(arr(acedata, i, CLONE).oldctg);
	  ch.dat[ 2] = htonl(arr(acedata, i, CLONE).ibc);
	  ch.dat[ 3] = htonl(arr(acedata, i, CLONE).x);
	  ch.dat[ 4] = htonl(arr(acedata, i, CLONE).y);
	  ch.dat[ 5] = htonl(arr(acedata, i, CLONE).mattype);
	  ch.dat[ 6] = htonl(arr(acedata, i, CLONE).parent);
	  ch.dat[ 7] = htonl(arr(acedata, i, CLONE).next);
	  ch.dat[ 8] = htonl(arr(acedata, i, CLONE).highcol);
	  ch.dat[ 9] = htonl(arr(acedata, i, CLONE).selected);
	  ch.dat[10] = htonl(arr(acedata, i, CLONE).class);
	  ch.dat[11] = htonl(arr(acedata, i, CLONE).seqstat);
	  ch.dat[12] = htonl(arr(acedata, i, CLONE).seqtype);

	  /*  */
	  /* sness - Write the markers */
	  /*  */

	  /* First, figure out how many markers we are working with */
	  nmark = 0;
	  clone = arrp(acedata,i,CLONE);
	  marker = clone->marker;
	  while (marker != NULL) {
		nmark++;
		marker = marker->nextmarker;
	  }
	  
	  /* nmark - Number of markers for this clone */
	  ch.dat[13] = htonl(nmark);

 	  /* Write out the full 'ch' data structure to 'socket' */
 	  if (write(socket, &ch, sizeof(ch)) != sizeof(ch)) return -1;

	  /* Following prints to stdout of client, so it shows up on the screen */
      /* printf("Clone %s\tMarkers %i\n",clone->clone,nmark); */

 	  /* Then, write each marker in sequence to 'socket' */
 	  if (nmark > 0) {
 		marker = clone->marker;
 		while (marker != NULL) {
 		  memcpy(&mch.buf[3*4], marker->marker, MARKER_SZ+1);
 		  mch.dat[0] = htonl(marker->markerindex);
 		  mch.dat[1] = htonl(marker->weak);
 		  mch.dat[2] = htonl(marker->new);
  		  if (write(socket, &mch, sizeof(mch)) != sizeof(mch)) return -1;
 		  marker = marker->nextmarker;
 		}
 	  }
	}

/*   for (i = 0; i < arrayMax(acedata); i++) { */
/* 	printf("Clone : i=%i\tname = %s\t%i\t%i\n",i,arr(acedata, i, CLONE).clone, */
/* 		   arr(acedata, i, CLONE).ctg,arr(acedata, i, CLONE).seqtype); */
/*   } */
	
  return 0;
}


/* */
/* Markerdata */
/* */
/* Read and write socket functions for sending markerdata */
/* */
/* sness */
/* */

union markerdata_chunk
{
  u_int32_t dat[12]; 
  char buf[12*4 + (MARKER_SZ+1)];  /* 'marker' (Marker name) */
};

int readMarkerdata(int socket)
{
  int  i,j;
  int size;
  union markerdata_chunk ch;

  if (readLoop(socket, &j, sizeof(j)) != sizeof(j)) return -1;
  size = ntohl(j);

/*   printf("j = %i\tsize = %i\n",j,size); */
  markerdata = arrayReCreate(markerdata, size+1, MARKER);

  for (i = 0; i < size; i++)
 	{
 	  if (readLoop(socket, &ch, sizeof(ch)) != sizeof(ch)) return -1;

 	  memcpy(arr(markerdata, i, MARKER).marker, &ch.buf[12*4], MARKER_SZ+1);

 	  arr(markerdata, i, MARKER).count      	= ntohl(ch.dat[0]);
 	  arr(markerdata, i, MARKER).type   		= ntohl(ch.dat[1]);
 	  arr(markerdata, i, MARKER).frame_type    	= ntohl(ch.dat[2]);
  	  arr(markerdata, i, MARKER).anchor        	= ntohl(ch.dat[3]);
 	  arr(markerdata, i, MARKER).box  			= ntohl(ch.dat[4]);
 	  arr(markerdata, i, MARKER).minicontigbox	= ntohl(ch.dat[5]);
 	  arr(markerdata, i, MARKER).colour     	= ntohl(ch.dat[6]);
 	  arr(markerdata, i, MARKER).status  		= ntohl(ch.dat[7]);
 	  arr(markerdata, i, MARKER).textbox 		= ntohl(ch.dat[8]);
 	  arr(markerdata, i, MARKER).textbox2    	= ntohl(ch.dat[9]);
 	  arr(markerdata, i, MARKER).cloneindex  	= ntohl(ch.dat[10]);
 	  arr(markerdata, i, MARKER).weak  			= ntohl(ch.dat[11]);
 	}

  array(markerdata, size, MARKER);
  arrayMax(markerdata) = size;
  /*arrayForceFeed(markerdata, size); */

/*   for (i = 0; i < size; i++) { */
/* 	printf("Marker : i=%i\tname = %s\t%i\t%i\n",i,arr(markerdata, i, MARKER).marker, */
/* 		   arr(markerdata, i, MARKER).count,arr(markerdata, i, MARKER).weak); */
/*   } */

/*   printf("done\n"); */

  return 0;
}

int writeMarkerdata(int socket)
{
  u_int32_t out;
  int i, j;
  union markerdata_chunk ch;

  out = htonl(((unsigned long int)arrayMax(markerdata)));	
  j = htonl(arrayMax(markerdata)); //Gaurav

  if (write(socket, &j, sizeof(j)) != sizeof(j)) return -1;
/*
   printf("max = %i\tj = %i\n",arrayMax(markerdata),j); */

  for (i = 0; i < arrayMax(markerdata); i++)
 	{
 	  memcpy(&ch.buf[12*4], arr(markerdata, i, MARKER).marker, MARKER_SZ+1);

 	  ch.dat[ 0] = htonl(arr(markerdata, i, MARKER).count);
 	  ch.dat[ 1] = htonl(arr(markerdata, i, MARKER).type);
 	  ch.dat[ 2] = htonl(arr(markerdata, i, MARKER).frame_type);
  	  ch.dat[ 3] = htonl(arr(markerdata, i, MARKER).anchor);
 	  ch.dat[ 4] = htonl(arr(markerdata, i, MARKER).box);
 	  ch.dat[ 5] = htonl(arr(markerdata, i, MARKER).minicontigbox);
 	  ch.dat[ 6] = htonl(arr(markerdata, i, MARKER).colour);
 	  ch.dat[ 7] = htonl(arr(markerdata, i, MARKER).status);
 	  ch.dat[ 8] = htonl(arr(markerdata, i, MARKER).textbox);
 	  ch.dat[ 9] = htonl(arr(markerdata, i, MARKER).textbox2);
 	  ch.dat[10] = htonl(arr(markerdata, i, MARKER).cloneindex);
 	  ch.dat[11] = htonl(arr(markerdata, i, MARKER).weak);

 	  /* Write out the full 'ch' data structure to 'socket' */
 	  if (write(socket, &ch, sizeof(ch)) != sizeof(ch)) return -1;

/* 	  printf("i = %i\tname = %s\t%i\t%i\n",i,arr(markerdata, i, MARKER).marker, */
/* 			 arr(markerdata, i, MARKER).count,arr(markerdata, i, MARKER).weak); */
 	}
	
  return 0;
}

int readMatrix(int socket)
{
	u_int32_t in;
	int i;
	u_int32_t row[17];

	if (readLoop(socket, &in, sizeof(in)) != sizeof(in)) return -1;
	Zcreate_instance("hello", &ZZ, ntohl(in));
	
	
	for (i = 0; i < ZZ.size; i++)
	{
	  if (readLoop(socket, &row, sizeof(row[0])*17) != sizeof(row[0])*17) return -1;

	  ZZ.matrix[i].set        = ntohl(row[0]);
	  ZZ.matrix[i].cbQ        = ntohl(row[2]);
	  ZZ.matrix[i].high_match = ntohl(row[3]);
	  ZZ.matrix[i].mtype      = ntohl(row[4]);
	  ZZ.matrix[i].pick       = ntohl(row[5]);
	  ZZ.matrix[i].box        = ntohl(row[6]);
	  ZZ.matrix[i].ebox       = ntohl(row[7]);
	  ZZ.matrix[i].grand      = ntohl(row[8]);
	  ZZ.matrix[i].save_grand = ntohl(row[9]);
	  ZZ.matrix[i].leftb      = ntohl(row[10]);
	  ZZ.matrix[i].rightb     = ntohl(row[11]);
	  ZZ.matrix[i].n_extra    = ntohl(row[12]);
	  ZZ.matrix[i].max_extra  = ntohl(row[13]);
	  ZZ.matrix[i].nbands     = ntohl(row[14]);
	  ZZ.matrix[i].n_cb       = ntohl(row[15]);
	  ZZ.matrix[i].cin        = ntohl(row[16]);
	  
	  ZZ.matrix[i].cb_index = NULL;
	  /* I don't think the 'extra' data is used until the greedy phase. Hence,
	   * we don't want it to be non-zero in daemon b/c then we'd free bad ptrs.
	   */
	  assert(ZZ.matrix[i].n_extra == 0);
		
	  ZZ.matrix[i].first = -1;
	}

	return 0;
}

int writeMatrix(int socket)
{
	u_int32_t out;
	int i;
	u_int32_t row[17];
	
	out = htonl(ZZ.size);
	
	if (write(socket, &out, sizeof(out)) != sizeof(out)) return -1;
	
		
	for (i = 0; i < ZZ.size; i++)
	{
		row[ 0] = htonl(ZZ.matrix[i].set);        
		row[ 2] = htonl(ZZ.matrix[i].cbQ);        
		row[ 3] = htonl(ZZ.matrix[i].high_match); 
		row[ 4] = htonl(ZZ.matrix[i].mtype);      
		row[ 5] = htonl(ZZ.matrix[i].pick);       
		row[ 6] = htonl(ZZ.matrix[i].box);        
		row[ 7] = htonl(ZZ.matrix[i].ebox);       
		row[ 8] = htonl(ZZ.matrix[i].grand);      
		row[ 9] = htonl(ZZ.matrix[i].save_grand); 
		row[10] = htonl(ZZ.matrix[i].leftb);      
		row[11] = htonl(ZZ.matrix[i].rightb);     
		row[12] = htonl(ZZ.matrix[i].n_extra);
		row[13] = htonl(ZZ.matrix[i].max_extra);  
		row[14] = htonl(ZZ.matrix[i].nbands);     
		row[15] = htonl(ZZ.matrix[i].n_cb);       
		row[16] = htonl(ZZ.matrix[i].cin);

		if (write(socket, &row, sizeof(row[0])*17) != sizeof(row[0])*17) return -1;
	}
	
	return 0;
}

int readDistrib(int socket)
{
	u_int32_t in;
	int i;
	u_int32_t value;
	int inbandmax;

	if (readLoop(socket, &in, sizeof(in)) != sizeof(in)) return -1;

        inbandmax = ntohl(in);

	if (inbandmax > 0) {
 	  bandmax = inbandmax;
	  validDistribution = 1;
	} else {
	  validDistribution = 0;
	  return 0;
	}

        if (!distrib) free(distrib);
        distrib = (float *) calloc(sizeof(float), bandmax*2);
	
	for (i = 0; i <= bandmax; i++)
	{
	  if (readLoop(socket, &distrib[i], sizeof(distrib[i])) 
                                         != sizeof(distrib[i]))
               return -1;

	}

	return 0;
}

int writeDistrib(int socket)
{
	u_int32_t out;
	int i;
	u_int32_t value;
	
	out = htonl(bandmax);
        if (!validDistribution) out = 0;
	if (write(socket, &out, sizeof(out)) != sizeof(out)) return -1;
	
	if (validDistribution) {
	  for (i = 0; i <= bandmax; i++)
	  {
  
		  if (write(socket, &distrib[i], sizeof(distrib[i])) 
                                              != sizeof(distrib[i]))
                      return -1;
	  }
	}
	  
	return 0;
}
